package com.wn.user.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.wn.common.entity.*;
import com.wn.common.pojo.AreaVillage;
import com.wn.common.pojo.User;
import com.wn.common.util.FileUtil;
import com.wn.user.auth.CookieUtil;
import com.wn.user.auth.JWTUtil;
import com.wn.user.feign.MessageFeign;
import com.wn.user.mapper.AreaVillageMappper;
import com.wn.user.mapper.UserMapper;
import com.wn.user.param.PropertyParam;
import com.wn.user.service.UserService;
import com.wn.user.util.Apply2AdminUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.logging.Logger;


import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @BelongsProject: shared_parking
 * @BelongsPackage: com.wn.user.service.impl
 * @Author: 廖刚
 * @CreateTime: 2020-06-10 19:53
 * @Description:
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AreaVillageMappper areaVillageMappper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private MessageFeign messageFeign;



    @Override
    public Integer addUser(User user) {
        Integer integer = userMapper.addUser(user);
        return integer;
    }

    /**
     * 查询所有用户 支持多条件分页排序查询
     * @param param
     * @return
     */
    @Override
    public Object getAllUser(MyParam<User> param) {
        if(StringUtil.isEmpty(param.getSuperSearchKeyWord())){
            //没有高级检索关键词，根据里面的数据普通分页排序查询
            PageHelper.startPage(param.getMyPage().getPageNum(),param.getMyPage().getPageSize());
            for(int i = 0; param.getPageParam() != null && i < param.getPageParam().length;i++){
                PageHelper.orderBy(param.getPageParam()[i]);
            }

            List<User> userList = userMapper.getAllUser(param.getT());
            PageInfo<User> userPageInfo = new PageInfo<>(userList);
            return userPageInfo;
        }else{
            //根据高级关键字，分页排序查询
            PageHelper.startPage(param.getMyPage().getPageNum(),param.getMyPage().getPageSize());
            for(int i = 0;param.getPageParam() != null && i < param.getPageParam().length;i++){
                PageHelper.orderBy(param.getPageParam()[i]);
            }

            List<User> userList = userMapper.superSearch(param.getSuperSearchKeyWord());
            PageInfo<User> userPageInfo = new PageInfo<>(userList);

            return userPageInfo;
        }
    }



    /**
     * 根据id获取用户对象
     * @param uId 用户id
     * @return
     */
    @Override
    public User getUserById(String uId) {
        User user = userMapper.getUserById(uId);
        return user;
    }

    /**
     * 通过用户名判断是否存在这样的用户
     * @param username 用户名
     * @return
     */
    @Override
    public boolean existUserByUsername(String username) {

        return userMapper.existUserByUsername(username) > 0;
    }

    /**
     * 通过id物理删除一个用户对象
     * @param uId 用户id
     * @return
     */
    @Override
    public Integer deleteUserTrueById(String uId) {
        Integer integer = userMapper.deleteUserTrueById(uId);
        return integer;
    }

    /**
     * 通过id逻辑删除一个用户对象
     * @param uId
     * @return
     */
    @Override
    public Integer deleteUserLogicalById(String uId) {
        Integer integer = userMapper.deleteUserLogicalById(uId);
        return integer;
    }

    /**
     * 恢复一个被逻辑删除的用户对象
     * @param uId
     * @return
     */
    @Override
    public Integer recoverUserById(String uId) {
        Integer integer = userMapper.recoverUserById(uId);
        return integer;
    }

    /**
     * 根据id来条件修改一个对象
     * @param user
     * @return
     */
    @Override
    public MyRsp updateUser(User user) {
        Integer integer = userMapper.updateUser(user);
        return integer > 0 ? MyRsp.success("修改成功"):MyRsp.error().msg("修改失败");
    }

    /**
     * 用户登录
     * @param user
     * @return
     */
    @Override
    public MyRsp login(User user, HttpServletResponse response) {
        User login = userMapper.login(user);
        if(login != null){//只有 登陆对象不为null且他的审核状态为1的时候 登录成功

            if (login.getStatus()!=1){//审核未通过

                //发送短信告诉用户审核未通过，请稍等

                return messageFeign.sendPhoneMsg(new PhoneMsgEntity(login.getTel(),null));
            }
            else {//通过审核
                //生成token字符串，需要将用户的id,username,role,code,isDeleted
                String token = JWTUtil.generateToken(login, 180);

                //存入cookie中发送到前端
                CookieUtil.responseCookie("token",token,10800,response);

                //返回登陆对象login
                return MyRsp.success(login).msg("用户登录成功");
            }
        }else{//登录失败

            return MyRsp.error().msg("用户名或者密码错误");
        }
    }

    /**
     * 抢租客注册
     * @param user
     * @return
     */
    @Override
    public MyRsp register(User user, String reg) {
        //首先判断验证码是否一致，如果一致，销毁redis中的键值对
        //System.out.println(user);
        //根据手机号获取数据库中的验证码
        String redisReg = redisTemplate.opsForValue().get(user.getUsername());
        //和用户输入做比较
        if(redisReg.equals(reg)){
            //验证码输入正确,删除这个验证码，并且返回正确值
            redisTemplate.delete(user.getUsername());
            //注册进入mysql数据库
            user.setUId(UUID.randomUUID().toString());
            user.setCreateUserId(user.getUId());
            user.setUpdateUserId(user.getUId());
            user.setRoleId(3);
            Integer integer = userMapper.addUser(user);
            return integer > 0 ? MyRsp.success("注册成功"):MyRsp.error().msg("注册失败");
        }else{
            return MyRsp.error().code(Const.Status.STATUS_WRONG_REQ).msg("验证码输入错误");
        }
    }

    /**
     * 用户忘记密码，根据手机号和验证码重置密码
     * @param user 包含用户的手机和新密码
     * @param reg
     * @return
     */
    @Override
    public MyRsp updatePass(User user, String reg) {
        //根据手机号获取数据库中的验证码
        String redisReg = redisTemplate.opsForValue().get(user.getUsername());
        //和用户输入做比较
        if(redisReg.equals(reg)){
            //验证码输入正确，根据手机号和新密码修改密码
            Integer integer = userMapper.updatePass(user);
            return integer > 0 ? MyRsp.success("密码重置成功"):MyRsp.error().msg("密码重置失败");
        }else{
            //验证码输入错误
            return MyRsp.error().code(Const.Status.STATUS_WRONG_REQ).msg("验证码输入错误");
        }
    }

    /**
     * 忘记密码时用户重置，数据库有这个用户才进行修改，需要发送验证码
     * @param username
     * @return
     */
    @Override
    public MyRsp getReg(String username) {
        Integer integer = userMapper.existUserByUsername(username);
        if(integer > 0){//手机号已注册,发送验证码,
            return messageFeign.sendPhoneMsg(new PhoneMsgEntity(username,null));
        }else{//手机号未注册
            return MyRsp.error().msg("还没注册过");
        }
    }

    /**
     * 根据手机号来判断手机号是否已注册，如果未注册，向手机发送验证码
     * @param username
     * @return
     */
    @Override
    public MyRsp getYanzhenma(String username) {
        Integer integer = userMapper.existUserByUsername(username);
        if(integer > 0){//手机号已注册
            return MyRsp.success("存在此用户名的用户").code(Const.Status.STATUS_HAS_name);
        }else{//手机号未注册
            //发送验证码
            return messageFeign.sendPhoneMsg(new PhoneMsgEntity(username,null));
        }
    }

    /**
     * 上传身份证图片到nginx中，并且将地址返回，存入到数据库
     * @param imgstr
     * @return
     */
    @Override
    public MyRsp uploadIdCardImg(String imgstr,String token) {
        User currentUser = JWTUtil.parseToken(token);
        if(currentUser == null){
            //说明token已经失效
            return MyRsp.error().msg("请重新登录").code(Const.Status.STATUS_NOT_LOGIN);
        }
        String imageUrl = FileUtil.uploadImage(imgstr);
        Integer integer = 0;
        if (imageUrl != null){
            currentUser.setIdcardImg(imageUrl);
            integer = userMapper.updateUser(currentUser);
        }
        return integer > 0? MyRsp.success("上传成功"):MyRsp.error().msg("上传失败");
    }




    /**
     * 用户实名认证，包含用户的真实姓名，还有用户的身份证号码
     * @param user
     * @param token 从token中取出uId
     * @return
     */
    @Override
    public MyRsp auth(User user, String token) {
        //解析token
        User currentUser = JWTUtil.parseToken(token);
        if(currentUser == null){
            //说明token已经失效
            return MyRsp.error().msg("请重新登录").code(Const.Status.STATUS_NOT_LOGIN);
        }else{
            //判断身份证图片是否已经上传
            if(userMapper.getUserById(currentUser.getUId()).getIdcardImg() == null){
                //没有上传
                return MyRsp.error().msg("身份证图片未上传").code(Const.Status.STATUS_NO_IDIMG);
            }
            //根据主键，添加身份信息
            //添加身份证
            currentUser.setIdCard(user.getIdCard());
            //添加真实姓名
            currentUser.setRealname(user.getRealname());
            currentUser.setEmail(user.getEmail());
            Integer integer = userMapper.updateUser(currentUser);
            //修改之后，向管理员发送邮件告诉他需要审核
            //告诉管理员哪个用户需要审核
            boolean b = Apply2AdminUtil.sendEmail(currentUser);

            return b ? MyRsp.success("修改成功"):MyRsp.error().msg("修改失败");
        }
    }

    /**
     * 获取用户信息
     * @param token
     * @return
     */
    @Override
    public MyRsp getUserInfo(String token) {
        User currentUser = JWTUtil.parseToken(token);
        if(currentUser == null){
            //说明token已经失效
            return MyRsp.error().msg("请重新登录").code(Const.Status.STATUS_NOT_LOGIN);
        }
        User user = userMapper.getUserById(currentUser.getUId());
        return user != null ? MyRsp.success(user):MyRsp.error().msg("获取用户信息失败");
    }

    /**
     * 用户退出登陆
     *
     * @param response
     * @return
     */
    @Override
    public MyRsp logout(HttpServletResponse response) {
        CookieUtil.responseCookie("token","------",180,response);
        return MyRsp.success("退出成功");
    }

    /**
     * 修改用户审核状态
     * @param user
     * @param token
     * @return
     */
    @Override
    public MyRsp setUserStatus(User user, String token) {

        Integer integer = userMapper.setUserStatus(user);

        //修改之后再获取修改后的数据
        MyRsp userInfoMsp = getUserInfo(token);



        if(userInfoMsp.getCode() == 0){

            User currentUser = (User) userInfoMsp.getContent();

            User userByIdTel = getUserByIdTel(user.getUId());


            if(userByIdTel.getStatus() == 1){//审核通过

                //发送消息通知用户审核通过了
                //*System.out.println(currentUser)
                messageFeign.sendPhoneMsg(new PhoneMsgEntity(userByIdTel.getTel(),null));
            }
        }
        return integer > 0 ? MyRsp.success("修改成功"):MyRsp.error().msg("修改失败");

    }

    /**
     * 修改用户状态
     * @param user
     * @return
     */
    /*@Override
    public MyRsp setUserStatus(User user,String token) {

        Integer integer = userMapper.setUserStatus(user);

        //修改之后再获取修改后的数据
        MyRsp userInfoMsp = getUserInfo(token);

        if(userInfoMsp.getCode() == 0){
            User currentUser = (User) userInfoMsp.getContent();
            if(currentUser.getStatus() == 1){//审核通过

                //发送消息通知用户审核通过了
                *//*System.out.println(currentUser);*//*
                messageFeign.sendPhoneMsg(new PhoneMsgEntity(currentUser.getTel(),null));
            }
        }
        return integer > 0 ? MyRsp.success("修改成功"):MyRsp.error().msg("修改失败");
    }*/

    /**
     * 修改用户状态
     * @param
     * @return
     */
    /*@Override
    public MyRsp setUserStatus(User user,String token) {
        Integer integer = userMapper.setUserStatus(user);
        //修改之后再获取修改后的数据
        MyRsp userInfoMsp = getUserInfo(token);
        if(userInfoMsp.getCode() == 0){
            User currentUser = (User) userInfoMsp.getContent();
            if(currentUser.getStatus() == 1){//审核通过
                //告诉用户审核通过了，发送邮件
                System.out.println(currentUser);
                Apply2AdminUtil.applySuccess(currentUser);
            }
        }
        return integer > 0 ? MyRsp.success("修改成功"):MyRsp.error().msg("修改失败");
    }

    /**
     * 显示抢租客需要审核的信息，
     * @param page
     * @param rows
     * @param superSearchKeyWord
     * @param status
     * @return
     */
    @Override
    public Object tenantList(Integer page, Integer rows, String superSearchKeyWord, Integer status,String sort,Integer roleId) {
        //封装一个MyParam
        MyParam<User> userMyParam = new MyParam<>();
        userMyParam.setMyPage(new MyPage(page,rows));
        userMyParam.setSuperSearchKeyWord(superSearchKeyWord);
        //排序规则，未审查的放在前面
        //先注册的先审查，createtime从小到大排序
        String[] pageParam = {sort,"createtime"};
        userMyParam.setPageParam(pageParam);
        User user = new User();
        user.setRoleId(roleId);
        if(status != null && status >= 0){
            user.setStatus(status);
        }
        userMyParam.setT(user);
        //需要同时满足搜索和审核状态
        PageInfo<User> userPageInfo = null;
        //无搜索，
        if(userMyParam.getSuperSearchKeyWord() == null || userMyParam.getSuperSearchKeyWord().equals("")){//无关键字
            userPageInfo = (PageInfo<User>) getAllUser(userMyParam);            //如果有关键字
        }else{//有关键字
            List<User> userList1 = userMapper.getAllUser(userMyParam.getT());
            List<User> userList2 = userMapper.superSearch(userMyParam.getSuperSearchKeyWord());
            userList1.retainAll(userList2);
            //封装到pageInfo中
            userPageInfo = new PageInfo<>(userList1);
        }

        HashMap<String, Object> map = new HashMap<>();
        if(userPageInfo != null){
            map.put("total",userPageInfo.getTotal());
            map.put("rows",userPageInfo.getList());
        }
        return map;
    }

    /**
     * 添加用户的车牌号码
     * @param
     * @return
     */
    @Override
    public MyRsp addCarNumber(User user,String token) {
        User currentUser = JWTUtil.parseToken(token);
        if(currentUser == null){
            //说明token已经失效
            return MyRsp.error().msg("请重新登录").code(Const.Status.STATUS_NOT_LOGIN);
        }
        currentUser.setCarNumber(user.getCarNumber());
        Integer integer = userMapper.updateUser(currentUser);
        return integer > 0 ? MyRsp.success("车牌号添加成功"):MyRsp.error().msg("车牌号添加失败");
    }

    /**
     * 对用户进行解锁和锁定
     * @param user
     * @return
     */
    @Override
    public MyRsp setUserCode(User user) {
        Integer integer = userMapper.updateUser(user);
        return integer > 0 ? MyRsp.success("修改成功"):MyRsp.error().msg("修改失败");
    }

    /**
     * 对抢租客的信息进行管理
     * @param page
     * @param rows
     * @param superSearchKeyWord
     * @param code
     * @return
     */
    @Override
    public Object tenantManage(Integer page, Integer rows, String superSearchKeyWord, Integer code,String pageParam,Integer roleId) {
        //封装一个MyParam
        MyParam<User> userMyParam = new MyParam<>();
        userMyParam.setMyPage(new MyPage(page,rows));
        User user = new User();
        user.setRoleId(roleId);
        //只显示已审查的
        user.setStatus(1);

        //将排序参数加进去
        if(pageParam != null){
            String[] split = pageParam.split(",");
            userMyParam.setPageParam(split);
        }
        if(code != null && code >= 0){
            user.setCode(code);
        }

        userMyParam.setT(user);
        userMyParam.setSuperSearchKeyWord(superSearchKeyWord);
        PageInfo<User> userPageInfo = null;
        //没有关键字搜索的时候
        if(userMyParam.getSuperSearchKeyWord() == null || userMyParam.getSuperSearchKeyWord().equals("")){//无关键字
            userPageInfo = (PageInfo<User>) getAllUser(userMyParam);            //如果有关键字
        }else{//有关键字搜索的时候
            List<User> userList1 = userMapper.getAllUser(userMyParam.getT());
            List<User> userList2 = null;
            if (roleId == 3){
                userList2 = userMapper.superSearch2(userMyParam.getSuperSearchKeyWord());
            }else if(roleId == 2){
                userList2 = userMapper.superSearch3(userMyParam.getSuperSearchKeyWord());
            }else if(roleId == 1){
                userList2 = userMapper.superSearch1(userMyParam.getSuperSearchKeyWord());
            }

            userList1.retainAll(userList2);
            //封装到pageInfo中
            userPageInfo = new PageInfo<>(userList1);
        }
        HashMap<String, Object> map = new HashMap<>();
        if(userPageInfo != null) {
            map.put("total", userPageInfo.getTotal());
            map.put("rows", userPageInfo.getList());
        }
        return map;
    }

    /**
     * 物业方注册
     * 如果在小区表中没有这个小区，则添加进去
     * @param propertyParam
     * @return
     */
    @Override
    public MyRsp propertyRegister(PropertyParam propertyParam) {
        if(propertyParam.getMainImgBase64() == null){
            return MyRsp.error().msg("请上传身份证图片").code(Const.Status.STATUS_NO_IDIMG);
        }

        Integer integer = userMapper.existUserByUsername(propertyParam.getUser().getUsername());
        if(integer > 0 ){//该用户名已经被注册
            return MyRsp.error().msg("该用户名已注册").code(Const.Status.STATUS_HAS_name);
        }
        //手机号重复性校验
        Integer integer2 = userMapper.existUserByTel(propertyParam.getUser().getTel());
        if(integer2 > 0){//该手机号已经注册
            return MyRsp.error().msg("该手机号已注册").code(Const.Status.STATUS_HAS_TEL);
        }
        //可以注册
        //判断该小区是否已经注册
//        System.out.println(propertyParam);
        //用户id
        String uId = UUID.randomUUID().toString();
        Integer integer1 = areaVillageMappper.existVillagerByAName(propertyParam.getVillage());
        if(integer1 > 0){
            //该小区已经被注册
            return MyRsp.error().code(Const.Status.STATUS_WRONG_REQ);
        }

        //未被注册，向小区表中加入一条数据
        //通过地区名获取地区id

        String aId = areaVillageMappper.getIdByAreaName(propertyParam.getAName());
        AreaVillage areaVillage = new AreaVillage();
        //添加id
        areaVillage.setAId(UUID.randomUUID().toString());
        //添加创建人id，说明这个小区是由这个物业管理
        areaVillage.setCreateUserId(uId);
        //添加父类id
        areaVillage.setParentId(aId);
        //添加小区名称
        areaVillage.setAName(propertyParam.getVillage());
        //添加小区的经纬度
        areaVillage.setLongitude(propertyParam.getLongitude());
        areaVillage.setLatitude(propertyParam.getLatitude());
        areaVillageMappper.addAreaVillage(areaVillage);
        //将图片上传至云端
        String imageUrl = FileUtil.uploadImage(propertyParam.getMainImgBase64());
        User user  = propertyParam.getUser();
        //将身份证图片路径注入
        user.setIdcardImg(imageUrl);
        //生成用户的主键
        user.setUId(uId);
        Integer result = userMapper.addUser(user);
        return result > 0 ? MyRsp.success("用户注册成功"):MyRsp.error().msg("用户注册失败");
    }

    /**
     * 出租方注册
     * @param propertyParam
     * @return
     */
    @Override
    public MyRsp lessorRegister(PropertyParam propertyParam) {
        if(propertyParam.getMainImgBase64() == null){
            return MyRsp.error().msg("请上传身份证图片").code(Const.Status.STATUS_NO_IDIMG);
        }
        //判断用户名是否被注册
        Integer integer = userMapper.existUserByUsername(propertyParam.getUser().getUsername());
        if(integer > 0 ){//该用户名已经被注册
            return MyRsp.error().msg("该用户名已注册").code(Const.Status.STATUS_HAS_name);
        }
        //可以注册
        //用户id
        String uId = UUID.randomUUID().toString();
        //获取需要添加的用户对象
        User user  = propertyParam.getUser();
        user.setUId(uId);
        user.setCreateUserId(uId);
        //将图片上传至云端
        String imageUrl = FileUtil.uploadImage(propertyParam.getMainImgBase64());
        //将身份证图片路径注入
        user.setIdcardImg(imageUrl);
        Integer result = userMapper.addUser(user);
        return result > 0 ? MyRsp.success("用户注册成功"):MyRsp.error().msg("用户注册失败");
    }

    /**
     *根据id获取到用户的电话号
     * @param uId
     * @return
     */
    @Override
    public User getUserByIdTel(String uId) {

        User userByIdTel = userMapper.getUserByIdTel(uId);
        return userByIdTel;

    }


}
